package com.andon.microcellsimulator.activity;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.andon.microcellsimulator.R;
import com.andon.microcellsimulator.common.adapter.CommonAdapter;
import com.andon.microcellsimulator.common.adapter.ViewHolder;
import com.andon.microcellsimulator.common.base.BaseActivity;
import com.andon.microcellsimulator.common.dialog.TitlePopup;
import com.andon.microcellsimulator.common.dialog.ZnkConfirmDialog;
import com.andon.microcellsimulator.common.mqtt.MQTTCallback;
import com.andon.microcellsimulator.common.mqtt.MQTTServiceManager;
import com.andon.microcellsimulator.common.socket.ServerCallback;
import com.andon.microcellsimulator.common.socket.ServerManager;
import com.andon.microcellsimulator.common.util.DateUtil;
import com.andon.microcellsimulator.common.util.JsonUtil;
import com.andon.microcellsimulator.common.util.LogUtil;
import com.andon.microcellsimulator.common.util.ZnkActivityUtil;
import com.andon.microcellsimulator.http.IOTClient;
import com.andon.microcellsimulator.http.response.DeviceBean;
import com.andon.microcellsimulator.http.response.GroupBean;
import com.andon.microcellsimulator.http.response.IOTCommunicateStepBean3;
import com.andon.microcellsimulator.http.response.RDSBean;
import com.andon.microcellsimulator.model.DeviceInfoModel;
import com.andon.microcellsimulator.model.DeviceModel;
import com.andon.microcellsimulator.model.GlobalBean;
import com.andon.microcellsimulator.model.GlobalBeanManager;
import com.andon.microcellsimulator.mqtt.BaseMessage;
import com.andon.microcellsimulator.mqtt.BindCommandMessage;
import com.andon.microcellsimulator.mqtt.BindingCommand;
import com.andon.microcellsimulator.mqtt.IssuedCommandMessage;
import com.andon.microcellsimulator.mqtt.MQTTMessageCallBack;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class DeviceListActivity extends BaseActivity {

    public final String TAG_CLASS_NAME = this.getClass().getSimpleName();
    private final int REQ_CODE_SCAN = 1;

    @Bind(R.id.device_list_header)
    RelativeLayout mDeviceListHeader;
    @Bind(R.id.device_list_title)
    TextView mDeviceListTitle;
    @Bind(R.id.device_list_view)
    ListView mDeviceListView;
    @Bind(R.id.device_command_content)
    TextView mDeviceCommandContent;

    // Menu
//    private TitlePopup titlePopup;

    private CommonAdapter<DeviceModel> mDeviceListAdapter;

    private List<DeviceModel> mDeviceListData;

    private Map<String, DeviceModel> mDeviceListMap;

    private ServerManager mServerManager;

    private List<String> mWhiteList;

    private String mMQTTServerAddr;

    private String mDeviceID;
    private String mRSA;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    getMqttServerAddr(msg.obj.toString());
                    break;
                case 1:
                    addMsg(msg.obj.toString());
                    break;
                case 2:
                    mDeviceListAdapter.notifyDataSetChanged();
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_device_list);
        ButterKnife.bind(this);
        setStatusBar(R.color.theme);

        initView();

        initData();
    }


    @OnClick({R.id.device_list_info, R.id.device_list_add_member})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.device_list_info:
                break;
            case R.id.device_list_add_member:
//                titlePopup.show(mDeviceListHeader);

                // 跳转到扫描二维码UI
                Intent intent = new Intent(DeviceListActivity.this, ScanMemberIDActivity.class);
                intent.putExtra("src", TAG_CLASS_NAME);
                startActivityForResult(intent, REQ_CODE_SCAN);
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK
                && requestCode == REQ_CODE_SCAN) {

            String result = data.getStringExtra("result");

            if (!TextUtils.isEmpty(result)) {

                DeviceInfoModel deviceInfoModel = JsonUtil.toObj(result, DeviceInfoModel.class);

                if (deviceInfoModel != null) {
                    mDeviceID = deviceInfoModel.getDeviceID();
                    mRSA = deviceInfoModel.getRsa();

                    LogUtil.i("设备ID:" + mDeviceID);

                    if (!TextUtils.isEmpty(mDeviceID) && !TextUtils.isEmpty(mRSA)) {
                        if (!TextUtils.equals(mDeviceID, GlobalBeanManager.getGlobalBean().getDeviceID())) {

                            mDeviceListTitle.setText(ZnkActivityUtil.getSubName(mDeviceID, 19));
                            addMsg("正在初始化为AP设备:[" + mDeviceID + "]");
                            // 如果打开了MQTT订阅,则关闭
                            MQTTServiceManager.stopMqttService(this);
                            // 初始化网络请求基础数据
                            IOTClient.getInstance().init(mRSA, mDeviceID);
                            // IoT登录
                            loginIoT();
                        }
                    } else {
                        Toast.makeText(this, "扫描的二维码信息不完整", Toast.LENGTH_LONG).show();
                    }

                } else {
                    Toast.makeText(this, "扫描的二维码信息错误", Toast.LENGTH_LONG).show();
                }

            } else {
                Toast.makeText(this, "扫描的二维码信息为空", Toast.LENGTH_LONG).show();
            }

        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {

            ZnkActivityUtil.showConfirmDialog(this, "确定要退出吗？", new ZnkConfirmDialog.OnClickCallBack() {
                @Override
                public void exec() {
                    // 结束所有activity
                    if (mServerManager != null) {
                        mServerManager.stopService();
                    }

                    MQTTServiceManager.stopMqttService(DeviceListActivity.this);

                    finish();
                    android.os.Process.killProcess(android.os.Process.myPid());
                    System.exit(0);
                }
            }, null);

            return true;
        }

        return false;
    }

    private void initView() {

        mDeviceCommandContent.setText("");
        mDeviceCommandContent.setMovementMethod(ScrollingMovementMethod.getInstance());

//        titlePopup = new TitlePopup(this);
//
//        titlePopup.setItemOnClickListener(new TitlePopup.OnItemOnClickListener() {
//            @Override
//            public void onItemClick(int position) {
//                // 点击设备菜单
//                if (position == 0) {
//                    // 跳转到扫描二维码UI
//                    Intent intent = new Intent(DeviceListActivity.this, ScanMemberIDActivity.class);
//                    intent.putExtra("src", TAG_CLASS_NAME);
//                    startActivityForResult(intent, REQ_CODE_SCAN);
//
//                } else if (position == 1) {
//                    // TODO:跳转到设置UI
//
//                }
//            }
//        });

        mDeviceListData = new ArrayList<>();
        mDeviceListMap = new HashMap<>();

        mDeviceListAdapter = new CommonAdapter<DeviceModel>(this, mDeviceListData, R.layout.item_device_list) {
            @Override
            public void convert(ViewHolder helper, final DeviceModel item) {

                if (TextUtils.isEmpty(item.getDeviceName())) {
                    helper.setText(R.id.item_device_list_name, ZnkActivityUtil.getSubName(item.getDid(), 19));
                } else {
                    helper.setText(R.id.item_device_list_name, ZnkActivityUtil.getSubName(item.getDeviceName(), 19));
                }

                if (item.getIsOnline() == 1) {
                    helper.setText(R.id.item_device_list_state, "在线");
                    helper.setTextColor(R.id.item_device_list_state, getResources().getColor(R.color.theme));
                } else {
                    helper.setText(R.id.item_device_list_state, "离线");
                    helper.setTextColor(R.id.item_device_list_state, getResources().getColor(R.color.normal_content));
                }

                helper.setOnClick(R.id.item_device_list, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
//                        sendCommand(item.getDid(), "小明", "****************");
                    }
                });

            }
        };

        mDeviceListView.setAdapter(mDeviceListAdapter);

        mWhiteList = new ArrayList<>();
    }

    private void initData() {

        new LocalAddressLoaderThread().start();

    }

    class LocalAddressLoaderThread extends Thread {
        String addr = null;

        @Override
        public void run() {
            try {
                addr = InetAddress.getLocalHost().getHostAddress();

                Message msg = mHandler.obtainMessage();
                msg.what = 0;
                msg.obj = addr;
                mHandler.sendMessage(msg);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

    }

    private void getMqttServerAddr(String ip) {

        if (!TextUtils.isEmpty(ip)) {
            // 获取服务器地址
            IOTClient.getInstance().getRDSProtocol("device-sub", ip,
                    new IOTClient.NetWorkCallBack() {
                        @Override
                        public void onSuccess(String json) {
                            RDSBean bean = JsonUtil.toObj(json, RDSBean.class);
                            if (bean != null && bean.getReturnValue() != null) {
                                mMQTTServerAddr = bean.getReturnValue().get(0).getAddrs().get(0);
                            }
                        }

                        @Override
                        public void onError(String result) {
                            addMsg("获取MQTT服务器地址失败:" + result);
                        }
                    });

        }
    }

    private void loginIoT() {

        addMsg("正在连接IoT服务器");

        // AP设备与云端认证
        IOTClient.getInstance().requestAPCommunicateToCloud(
                new IOTClient.NetWorkCallBack() {
                    @Override
                    public void onSuccess(String json) {
                        addMsg("登录IoT服务器成功");

                        startMqttService();
                        getDeviceList();

                    }

                    @Override
                    public void onError(String result) {
                        LogUtil.w(result);
                        Toast.makeText(DeviceListActivity.this, result, Toast.LENGTH_LONG).show();
                    }
                });
    }

    private void startMqttService() {

        // 判断MQTT服务器地址是否为空
        if (!TextUtils.isEmpty(mMQTTServerAddr)) {
            LogUtil.i("正在开启MQTT订阅");
            addMsg("正在开启MQTT订阅");

            MQTTServiceManager.init(mMQTTServerAddr);

            // 订阅MQTT
            MQTTServiceManager.startMqttService(this, GlobalBeanManager.getGlobalBean().getDeviceID(),
                    new MQTTMessageCallBack() {
                        @Override
                        public void getSrcMessage(String msg) {
                            addMsgBySubThread("MQTT接收到消息:[" + msg + "]");
                        }

                        @Override
                        public void issuedCommand(IssuedCommandMessage msg) {
                            sendCommand(msg.getDid(), msg.getCmd(), msg.getSid());
                        }

                        @Override
                        public void bindCommand(BindCommandMessage msg) {
                            // 处理CP设备的绑定与解绑
                            if (msg.getBindings() != null && msg.getBindings().size() > 0) {

                                DeviceModel model = null;

                                // 将设备添加到白名单
                                for (BindingCommand cmd : msg.getBindings()) {
                                    if (!mDeviceListMap.containsKey(cmd.getDid())) {
                                        model = new DeviceModel();
                                        model.setDid(cmd.getDid());
                                        model.setType(cmd.getType());
                                        model.setAsl(cmd.getAsl());
                                        model.setAuthinfo(cmd.getAuthInfo());
                                        model.setDtype(cmd.getDtype());
                                        model.setCommProtocol(cmd.getCommProtocol());
                                        model.setIsOnline(0);
                                        mDeviceListMap.put(cmd.getDid(), model);
                                        mWhiteList.add(cmd.getDid());
                                        mDeviceListData.add(model);
                                        updateDeviceList();
                                    }
                                }
                            }

                            if (msg.getUnbinding() != null && msg.getUnbinding().size() > 0) {

                                for (String deviceID : msg.getUnbinding()) {
                                    if (mDeviceListMap.containsKey(deviceID)) {
                                        // 从白名单中删除并断开与解绑设备的连接
                                        mDeviceListMap.remove(deviceID);
                                        mWhiteList.remove(deviceID);
                                        mServerManager.setWhiteList(mWhiteList);
                                        mServerManager.stopConnect(deviceID);

                                        DeviceModel tag = null;

                                        for (DeviceModel model : mDeviceListData) {
                                            if (TextUtils.equals(model.getDid(), deviceID)) {
                                                tag = model;
                                                break;
                                            }
                                        }

                                        if (tag != null) {
                                            mDeviceListData.remove(tag);
                                        }

                                        updateDeviceList();
                                    }
                                }
                            }

                        }
                    });
        }

    }

    // 刷新设备列表
    private void updateDeviceList() {
        mHandler.sendEmptyMessage(2);
    }

    private void getDeviceList() {

        LogUtil.i("正在获取组信息");
        addMsg("正在获取组信息");

        // 获取所在组及白名单
        IOTClient.getInstance().getGroupList(GlobalBeanManager.getGlobalBean().getAccessToken(),
                new IOTClient.NetWorkCallBack() {
                    @Override
                    public void onSuccess(String json) {

                        GroupBean jsonBean = JsonUtil.toObj(json, GroupBean.class);

                        if (jsonBean != null && jsonBean.getReturnValue() != null) {

                            mDeviceListData.clear();
                            mDeviceListMap.clear();
                            mWhiteList.clear();

                            if (jsonBean.getReturnValue().getDevices() != null
                                    && jsonBean.getReturnValue().getDevices().size() > 0) {

                                DeviceModel deviceModel = null;

                                for (DeviceBean bean : jsonBean.getReturnValue().getDevices()) {
                                    if (TextUtils.equals("CP", bean.getType())) {
                                        deviceModel = new DeviceModel(bean);
                                        mDeviceListData.add(deviceModel);
                                        mDeviceListMap.put(bean.getDid(), deviceModel);
                                        mWhiteList.add(bean.getDid());
                                    }
                                }
                            }

                            addMsg("当前组里包含" + mWhiteList.size() + "个CP设备, 白名单:" + mWhiteList.toString());

                            mDeviceListAdapter.notifyDataSetChanged();

                            searchDevice();
                        }

                    }

                    @Override
                    public void onError(String result) {
                        LogUtil.w(result);
                        Toast.makeText(DeviceListActivity.this, result, Toast.LENGTH_LONG).show();
                    }
                });

    }

    private void searchDevice() {

        mServerManager = ServerManager.getInstance();

        mServerManager.setServerCallback(new ServerCallback() {
            @Override
            public void deviceOnline(String deviceID) {
                addMsg("cp设备[" + deviceID + "]已连接");
                if (mDeviceListMap.containsKey(deviceID)) {
                    mDeviceListMap.get(deviceID).setIsOnline(1);
                    mDeviceListAdapter.notifyDataSetChanged();
                }

                // AP发起CP绑定
                IOTClient.getInstance().requestCPEquipmentJoin(GlobalBeanManager.getGlobalBean().getAccessToken(), new String[]{deviceID},
                        new IOTClient.NetWorkCallBack() {
                            @Override
                            public void onSuccess(String json) {
                                addMsg("上报cp设备[" + json + "]上线成功");
                            }

                            @Override
                            public void onError(String result) {
                                addMsg("上报cp设备上线失败:" + result);
                            }
                        });
            }

            @Override
            public void deviceOffline(String deviceID) {
                addMsg("cp设备[" + deviceID + "]已断开");
                if (mDeviceListMap.containsKey(deviceID)) {
                    mDeviceListMap.get(deviceID).setIsOnline(0);
                    mDeviceListAdapter.notifyDataSetChanged();
                }

                // AP发起CP绑定
                IOTClient.getInstance().requestCPEquipmentDisJoin(GlobalBeanManager.getGlobalBean().getAccessToken(), new String[]{deviceID},
                        new IOTClient.NetWorkCallBack() {
                            @Override
                            public void onSuccess(String json) {
                                addMsg("上报cp设备[" + json + "]离线成功");
                            }

                            @Override
                            public void onError(String result) {
                                addMsg("上报cp设备离线失败:" + result);
                            }
                        });
            }

            @Override
            public void recvDeviceMsg(String deviceID, String msg, String sid) {
                addMsg("cp设备[" + deviceID + "] 发送指令:[" + msg + "]");

                IOTClient.getInstance().equipmentDataUpload(deviceID, GlobalBeanManager.getGlobalBean().getAccessToken(), msg, mDeviceListMap.get(deviceID).getType(), sid,
                        new IOTClient.NetWorkCallBack() {
                            @Override
                            public void onSuccess(String json) {
                                addMsg("上报数据成功");
                            }

                            @Override
                            public void onError(String result) {
                                addMsg("上报数据失败:" + result);
                            }
                        });

            }
        });

        mServerManager.setWhiteList(mWhiteList);

        mServerManager.startService();

        addMsg("已开启本地tcp & udp服务,等待CP设备接入");

    }

    private void sendCommand(String deviceID, String command, String sid) {
        mServerManager.sendCommand(deviceID, command, sid);
        addMsgBySubThread("已向设备[" + deviceID + "]发送数据:" + command);
    }

    private void addMsg(String content) {

        mDeviceCommandContent.append(DateUtil.getNowDateTime() + " " + content + "\r\n");

        int offset = mDeviceCommandContent.getLineCount() * mDeviceCommandContent.getLineHeight();

        if (offset > mDeviceCommandContent.getHeight()) {
            mDeviceCommandContent.scrollTo(0, offset - mDeviceCommandContent.getHeight());
        }
    }

    private void addMsgBySubThread(String content) {
        Message msg = mHandler.obtainMessage();
        msg.what = 1;
        msg.obj = content;
        mHandler.sendMessage(msg);
    }
}
